/* $Id: lib.sig.c 397 2007-11-26 19:04:00Z mblack $
 * Copyright (C) 2007 Platform Computing Inc
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 */

#include "lib.h"

#define SIGEMT  SIGBUS
#define SIGLOST SIGIO
#define SIGIOT  SIGABRT

#if !defined(SIGWINCH) && defined(SIGWINDOW)
#    define SIGWINCH SIGWINDOW
#endif

int sig_map[] = {0,
                 SIGHUP,
                 SIGINT,
                 SIGQUIT,
                 SIGILL,
                 SIGTRAP,
                 SIGIOT,
                 SIGEMT,
                 SIGFPE,
                 SIGKILL,
                 SIGBUS,
                 SIGSEGV,
                 SIGSYS,
                 SIGPIPE,
                 SIGALRM,
                 SIGTERM,
                 SIGSTOP,
                 SIGTSTP,
                 SIGCONT,
                 SIGCHLD,
                 SIGTTIN,
                 SIGTTOU,
                 SIGIO,
                 SIGXCPU,
                 SIGXFSZ,
                 SIGVTALRM,
                 SIGPROF,
                 SIGWINCH,
                 SIGLOST,
                 SIGUSR1,
                 SIGUSR2
};

char *sigSymbol[] = {           "",
                                "HUP",
                                "INT",
                                "QUIT",
                                "ILL",
                                "TRAP",
                                "IOT",
                                "EMT",
                                "FPE",
                                "KILL",
                                "BUS",
                                "SEGV",
                                "SYS",
                                "PIPE",
                                "ALRM",
                                "TERM",
                                "STOP",
                                "TSTP",
                                "CONT",
                                "CHLD",
                                "TTIN",
                                "TTOU",
                                "IO",
                                "XCPU",
                                "XFSZ",
                                "VTALRM",
                                "PROF",
                                "WINCH",
                                "LOST",
                                "USR1",
                                "USR2"
};

int NSIG_MAP = (sizeof(sig_map)/sizeof(int));

int
sig_encode(int sig)
{
    int i;

    if (sig < 0)
        return sig;

    for (i=0; i<NSIG_MAP; i++)
        if (sig_map[i] == sig)
            break;
    if (i == NSIG_MAP) {
        if (sig >= NSIG_MAP)
            return(sig);
        else
            return(0);
    } else
        return(i);
}

int
sig_decode(int sig)
{
    if (sig < 0)
        return sig;

    if (sig >= NSIG_MAP) {
        if (sig < NSIG)
            return(sig);
        else {
            return(0);
        }
    }

    return(sig_map[sig]);
}

int
getSigVal(char *sigString)
{
    int sigVal, i;
    char sigSig[16];

    if (sigString == NULL)
        return -1;
    if (sigString[0] == '\0')
        return -1;

    if (isint_(sigString) == TRUE) {
        if ((sigVal=atoi(sigString)) > NSIG)
            return -1;
        else
            return (sigVal);
    }

    for (i=0; i<NSIG_MAP; i++) {
        sprintf(sigSig, "%s%s", "SIG", sigSymbol[i]);
        if ((strcmp(sigSymbol[i], sigString) == 0)
            || (strcmp( sigSig, sigString) == 0))
            return (sig_map[i]);
    }
    return -1;

}

char *
getSigSymbolList (void)
{
    static char list[512];
    int i;

    list[0] = '\0';
    for (i=1; i<NSIG_MAP; i++) {
        strcat(list, sigSymbol[i]);
        strcat(list, " ");
    }
    return(list);

}

SIGFUNCTYPE Signal_(int sig, void (*handler)(int))
{
    struct sigaction act, oact;

    act.sa_handler = handler;
    act.sa_flags = 0;
    sigemptyset(&act.sa_mask);
    sigaddset(&act.sa_mask, sig);
    if(sigaction(sig, &act, &oact) == -1){
        oact.sa_handler = (void (*)())SIG_ERR;
    }
    return(oact.sa_handler);
}

char *
getSigSymbol (int sig)
{
    static char symbol[30];

    symbol[0] = '\0';
    if (sig < 0 || sig >= NSIG_MAP)
        strcpy(symbol, "UNKNOWN");
    else
        strcpy(symbol, sigSymbol[sig]);
    return (symbol);

}

int
blockALL_SIGS_(sigset_t *newMask, sigset_t *oldMask)
{
    sigfillset(newMask);
    sigdelset(newMask, SIGTRAP);
    sigdelset(newMask, SIGEMT);
    return (sigprocmask(SIG_BLOCK, newMask, oldMask));
}
